# -*- coding: utf-8 -*-

# Copyright (c) 2011, Sergey Karakovskiy, Nikolay Sohryakov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Yasker nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from Queue import Queue
from datetime import datetime
import json
import logging
from util import storage, settings
import protocol_handlers
import xmpp_service
from Keys import *

__author__ = 'Nikolay Sohryakov, Sergey Karakovskiy'
__copyright__ = 'Copyright 2011, Yasker'
__license__ = 'New BSD'
__email__ = 'Nikolay.Sohryakov+yasker@gmail.com, Sergey.Karakovskiy+yasker@gmail.com'


class Events():
	GET_ALL_PROJECTS = 42
	GET_PROJECT_MILESTONES = 52
	GET_MILESTONE_TASKS = 62
	ADD_PROJECT = 72
	ADD_MILESTONE = 82
	ADD_TASK = 92
	UPDATE_PROJECT_DETAILS = 102
	UPDATE_MILESTONE_DETAILS = 112
	UPDATE_TASK_DETAILS = 122
	DELETE_PROJECT = 132
	DELETE_MILESTONE = 142
	DELETE_TASK = 152


events_queue = None


def init_core(_events_queue):
	global events_queue
	events_queue = _events_queue
	xmpp_service.register_incoming_callback(
		protocol_handlers.response_dispatcher)

active_user_jid = None

def login(jid, pwd):
	connection_details = {
		'jid': jid,
		'pwd': pwd,
		'host': 'talk.google.com',
		'port': 5223
	}
	connected = xmpp_service.connect(connection_details)
	if not connected:
		#TODO: return the reason too
		logging.error('Unable to connect. Wrong jid/password?')
		return False
	global active_user_jid
	active_user_jid = connection_details['jid']
	return True


def init_storage(jid):
	storage.connect(settings.getDatabasePath(jid))


def process_credentials(jid, pwd, is_save_cred, is_auto_login):
	if is_save_cred:
		settings.saveCredentials(jid, pwd, is_auto_login)

def _normalizeValue(val):
	"""
	Get object as a string.
	"""
	if val is None:
		return 'None'
	else:
		return val

def get_all_projects():
	"""
	Get a list of all projects.
	"""
	projects_list = storage.get_all_projects()
	projects_dicts_list = []
	for project in projects_list:
		projects_dicts_list.append({
			PROJECT_ID: _normalizeValue(project[0]),
			TITLE: _normalizeValue(project[1]),
			DESCRIPTION: _normalizeValue(project[2]),
		})
	return projects_dicts_list


#	PROJECT
def create_project(project_details):
	request = {
		TYPE: TYPE_ADD, #TODO: replace ADD with CREATE here and in all functions below and in server.
		RESOURCE: PROJECT,
		DETAILS: {
			PROJECT_ID: _generate_uid('p'),
			TITLE: project_details['title'],
			DESCRIPTION: project_details['description'],
		}
	}
	xmpp_service.send('yasker-project@appspot.com', request)


def edit_project():
	pass


def delete_project():
	pass


#	TASK
def get_root_tasks(p_id):
	tasks_list = storage.get_root_tasks(p_id)
	tasks_dicts_list = []
	for task in tasks_list:
		tasks_dicts_list.append({
			PROJECT_ID: _normalizeValue(task[0]),
			TASK_ID: _normalizeValue(task[2]),
			TITLE: _normalizeValue(task[3]),
			DESCRIPTION: _normalizeValue(task[4]),
			})
	return tasks_dicts_list


def get_sub_tasks(t_id):
	tasks_list = storage.get_sub_tasks(t_id)
	tasks_dict_list = []
	for task in tasks_list:
		tasks_dict_list.append({
			PROJECT_ID: _normalizeValue(task[0]),
		    TASK_PARENT: _normalizeValue(task[1]),
			TASK_ID: _normalizeValue(task[2]),
			TITLE: _normalizeValue(task[3]),
			DESCRIPTION: _normalizeValue(task[4]),
		})
	return tasks_dict_list


def create_task(task_details):
	request = {
		TYPE: TYPE_ADD,
	    RESOURCE: TASK,
	    DETAILS: {
		    PROJECT_ID: task_details[PROJECT_ID],
	        TASK_ID: _generate_uid('t'),
	        TASK_PARENT: task_details[TASK_PARENT],
	        TITLE: task_details[TITLE],
	        DESCRIPTION: task_details[DESCRIPTION],
	    }
	}
	xmpp_service.send('yasker-project@appspot.com', request)


def edit_task():
	pass


def delete_task():
	pass

#	COMMENT
def add_comment():
	pass


def edit_comment():
	pass


def delete_comment():
	pass


def _generate_uid(uid_type):
	"""
	<JID>%timestamp (YY-MM-DD-HH-MM-SS-MS) UTC time
	example: Sergey.Karakovskiy@gmail.com%<p,m,t,c>%2011-07-21-14-13-47-328
	Finally, all special symbols are replaced with '_' symbol.
	"""
	global active_user_jid
	replacer = lambda(x): len(x[0]) > 0 and replacer((x[0][1:], x[1].replace(x[0][0], '_'))) or x[1]
	uid = "%s_%s%s" % (active_user_jid, uid_type, str(datetime.now()))
	uid = replacer((['%', '.', ':', '-', '@', ' '], uid))
	return uid

